package com.beidouin.GnssMain;

import com.beidouin.GnssMain.models.PilotInfo;
import com.friendlyarm.AndroidSDK.HardwareControler;

import java.io.IOException;
import java.security.InvalidParameterException;

/**
 * Created by flyingfluff on 16/9/12.
 */
public class SerialPortReader {

    private static final boolean isTest=false;

    private static final String TAG = "SerialPort";
    public static void init() { sInstance = new SerialPortReader();}
    private static SerialPortReader sInstance;
    public static SerialPortReader getInstance() { return sInstance; }
    private boolean readyToSendBinnary=false;
    private boolean isEphemerisReady=false;
    private int mComIndex = -1;
    synchronized private void setReadyToSendBinnary(boolean ready){readyToSendBinnary=ready;}
    private StringBuilder cmdREC=new StringBuilder();


    public SerialPortReader(){
        try {
            //init serial port
            OpenSerialPort(1);
            mReadThread1 = new ReadThread1();
            mReadThread1.start();
/*
            devfd2 = HardwareControler.openSerialPort( devName2, speed2, dataBits2, stopBits2 );
            mReadThread2 = new ReadThread2();
            mReadThread2.start();
*/
        } catch (SecurityException e) {
            System.out.println("Exception :" + e);
        } catch (InvalidParameterException e) {
            System.out.println("Exception :" + e);
        }
    }



    /******************************NMEA串口********************************/
    private final int MAXLINES = 800;
    private StringBuilder remoteData = new StringBuilder(256 * MAXLINES);

    private static final String devName = isTest?"dev/ttyAMA2":"dev/ttyAMA3";
    private static final int speed = 115200;
    private static final int dataBits = 8;
    private static final int stopBits = 1;

    private int devfd = -1;
    private final int BUFSIZE = 4096;
    private byte[] bufFromSerial = new byte[BUFSIZE];
    private byte[] bufFromFile = new byte[BUFSIZE];
    private boolean isDataFromFile=false;
    private boolean serialPort_key=true;
    private boolean wasRecording=false;


    private ReadThread1 mReadThread1;
    private volatile boolean isSend2Port1 = true;


    public void set_isDataFromFile(boolean b) {isDataFromFile = b;}
    public boolean get_isDataFromFile(){return isDataFromFile;}

    private class ReadThread1 extends Thread {

        @Override
        public void run() {
            super.run();
            while(!isInterrupted()) {
                if(FileManager.getInstance().get_FileStreamSta()==FileManager.NORMAL) {
                    if(!serialPort_key)
                    {
                        //OpenSerialPort();
                        serialPort_key=true;
                    }
                    if (HardwareControler.select(devfd, 0, 0) == 1) {
                        int retSize = HardwareControler.read(devfd, bufFromSerial, BUFSIZE);
                        if (retSize > 0) {
                            PilotInfo.getInstance().HandleSerialData(bufFromSerial, retSize);
                        }
                    }
                }
                else if(FileManager.getInstance().get_FileStreamSta()==FileManager.ISRECORDING)
                {
                    if (HardwareControler.select(devfd, 0, 0) == 1) {
                        int retSize = HardwareControler.read(devfd, bufFromSerial, BUFSIZE);
                        if (retSize > 0) {
                            PilotInfo.getInstance().HandleSerialData(bufFromSerial, retSize);
                        }
                    }
                }
                else {
                    if(serialPort_key)
                    {
                        //StopSerialPort();
                        serialPort_key=false;
                    }
                    if(FileManager.getInstance().get_isNewData()) {
                        try {
                            setReadyToSendBinnary(true);
                            sleep(1000);
                            FileManager.getInstance().Finish_sleep();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    else {
                        try {
                            bufFromFile=FileManager.getInstance().ReadFile();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        int retSize =bufFromFile.length;
                        if (retSize > 0) {
                            PilotInfo.getInstance().HandleSerialData(bufFromFile, retSize);
                        }
                    }
                }
            }
        }
    }


    public void CloseSerialPort() {
        if (devfd != -1) {
            HardwareControler.close(devfd);
            devfd = -1;
        }
    }

    public void StopSerialPort()
    {
        HardwareControler.close(devfd);
    }
    public void OpenSerialPort(int comIndex)
    {
        if (comIndex != 1 && comIndex != 2)
            return;

        if (mComIndex == comIndex)
            return;
        mComIndex = comIndex;

        CloseSerialPort();

        if (mComIndex == 1)
            devfd=HardwareControler.openSerialPort( "dev/ttyAMA2", speed, dataBits, stopBits );
        else
            devfd=HardwareControler.openSerialPort( "dev/ttyAMA3", speed, dataBits, stopBits );
    }


    public void StopThread1() { mReadThread1.interrupt(); }




    public boolean getIsSend2Port1()
    {
        /*return isSend2Port1;*/
        return true;
    }
    public void setIsSend2Port1(boolean isSend) {/*isSend2Port1 = isSend;*/ }



    /******************************原始观测量串口********************************/
    private final int MAXLINES2 = 800;
    private StringBuilder remoteData2 = new StringBuilder(256 * MAXLINES2);

    private static final String devName2 =isTest?"dev/ttyAMA3": "dev/ttyAMA2";
    private static final int speed2 = 115200;
    private static final int dataBits2 = 8;
    private static final int stopBits2 = 1;

    private int devfd2 = -1;
    private final int BUFSIZE2 = 4096;
    private byte[] bufFromSerial2 = new byte[BUFSIZE2];
    private byte[] bufFromFile2 = new byte[BUFSIZE2];
    private boolean isDataFromFile2=false;
    private boolean serialPort_key2=true;


    private ReadThread2 mReadThread2;
    private volatile boolean isSend2Port2 = true;


    public void set_isDataFromFile2(boolean b) {isDataFromFile2 = b;}
    public boolean get_isDataFromFile2(){return isDataFromFile2;}

    private class ReadThread2 extends Thread {

        @Override
        public void run() {
            super.run();
            while(!isInterrupted()) {
                if(FileManager.getInstance().get_FileStreamSta()==FileManager.ISRECORDING) {
                    if (!isEphemerisReady) {
                        String s="$PCMDU\r\n";
                        if(HardwareControler.write(devfd2,s.getBytes())>0)
                        {
                            isEphemerisReady=true;
                        }
                    }
                    if (HardwareControler.select(devfd2, 0, 0) == 1) {
                        int retSize = HardwareControler.read(devfd2, bufFromSerial2, BUFSIZE2);
                        if (retSize > 0) {
                            PilotInfo.getInstance().HandleSerialData_Binnary(bufFromSerial2, retSize, FileManager.ISRECORDING);
                        }
                    }
                }
                else if(FileManager.getInstance().get_FileStreamSta()==FileManager.ISPLAYING){
                    if(readyToSendBinnary)
                    {
                        //发送数据
                        try {
                            bufFromFile2=FileManager.getInstance().ReadFile2();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        int retSize =bufFromFile2.length;
                        if (retSize > 0) {
                            HardwareControler.write(devfd2,bufFromFile2);
                            //String s=new String(bufFromFile2);
                            setReadyToSendBinnary(false);
                        }

                        //接收数据
                        if (HardwareControler.select(devfd2, 0, 0) == 1) {
                            int retSize2 = HardwareControler.read(devfd2, bufFromSerial2, BUFSIZE2);
                            if (retSize2 > 0) {
                                String s=new String(bufFromSerial2,0,retSize2);
                                if(s.contains("$PCMDU\r\n"))
                                {
                                    HardwareControler.write(devfd2,FileManager.getInstance().getEPHDATA());
                                }
                                PilotInfo.getInstance().HandleSerialData_FromPC(bufFromSerial2, retSize2);
                            }
                        }
                    }
                }
                else
                {
                    if (HardwareControler.select(devfd2, 0, 0) == 1) {
                        int retSize = HardwareControler.read(devfd2, bufFromSerial2, BUFSIZE2);
                        if (retSize > 0) {
                            PilotInfo.getInstance().HandleSerialData_Binnary(bufFromSerial2, retSize,FileManager.NORMAL);
                        }
                    }
                }
            }
        }
    }

    public void CloseSerialPort2() {
        if (devfd2 != -1) {
            HardwareControler.close(devfd2);
            devfd2 = -1;
        }
    }

    private void StopSerialPort2()
    {
        HardwareControler.close(devfd2);
    }
    public void OpenSerialPort2()
    {
        devfd2=HardwareControler.openSerialPort( devName2, speed2, dataBits2, stopBits2 );
    }


    public void StopThread2() {

        if(mReadThread2 != null){
            mReadThread2.interrupt();
        }
    }


    public boolean getIsSend2Port2()
    {
        /*return isSend2Port1;*/
        return true;
    }
    public void setIsSend2Port2(boolean isSend) {/*isSend2Port1 = isSend;*/ }


}

